/**
 * 对中间件进行操作
 */
import fs from 'fs'
 
// 导入配置
import ConfigHandler from "../init/ConfigHandler";
// 导入route控制器
import RouterHandler from "../route/RouterHandler";
// 导入类控制器
import Class from "../utils/Class";
// 导入颜色
import color from "../utils/Color";
// 导入语法糖解析器
import sugar from "../core/sugar"
import ControllerStructure from '../model/ControllerStructure';
import ErrorUtils from '../utils/ErrorUtils';

export = class Middleware {
    /**
     * 自动解析中间件
     * @param id          文件路径
     * @param target      目标数据，被解析的数据 可以是字符串或字符串数组
     * @param methodName  方法名称，可选
     * @returns 
     */
    public static auto_pars(id:string,target:string,methodName?:string):ControllerStructure;
    public static auto_pars(id:string,target:Array<string>,methodName?:string):ControllerStructure[];
    public static auto_pars(id:string,target:string|Array<string>,methodName:string="default") :ControllerStructure | ControllerStructure[]{
        let pars = (id:string,target:any,methodName:string="default"):ControllerStructure=>{
            switch (typeof target){
                case "string":{
                    //开始解析 asd:1,2,3
                    let index = target.includes(":") ? target.indexOf(":") : target.length;
                    // 解析出中间件的地址
                    let middname = target.substring(0,index);
                    // 从中间件池中获取到中间件，这个存在缓存问题
                    let middleware_module = RouterHandler.getMiddleware(middname);
                    // 如果不存在
                    if(middleware_module !== undefined){
                        let {module,methodName} = middleware_module;
                        // 已经解析过了进行一定的封装后返回
                        return new ControllerStructure(methodName,module.run,target.substring(index+1).split(",").filter(e=>e));
                    }else{
                        // 不存在说明是一个文件路径
                        let filepath = ConfigHandler.getMiddleware(middname) || ConfigHandler.getMiddleware(id);
                        if(!filepath){
                            console.log(color("红色",middname),"不存在");
                            console.log(color("红色",id));
                            ErrorUtils.error("middleware thereIsnot")
                        }
                        if(!fs.existsSync(filepath)){
                          if(sugar.path(filepath)){
                            filepath = sugar.path(filepath);
                          }else{
                            filepath = ConfigHandler.getAddress("middleware") + "/" + ConfigHandler.getMiddleware(middname);
                          };
                        }
                        // 缓存一下
                        RouterHandler.addMiddleware(middname,Middleware.pars_string_middleware(filepath,middname,[]));
                        // 开始解析
                        return Middleware.pars_string_middleware(filepath,middname,target.substring(index+1).split(",").filter(e=>e));
                    }
                }
                case "function":{
                    // 这是匿名中间件不需要放到中间件池, 直接生成中间件对象返回
                    return Middleware.createMiddleware(id,target,"anonymous",[])
                }
                case "object":{
                    // 这是匿名中间件不需要放到中间件池, 直接生成中间件对象返回
                    if(Array.isArray(target)){
                        let parse = (e:any)=>{
                            try{return JSON.parse(e)}catch{return e;}
                        }
                        // 数组的情况下[0]是方法或者对象[1]是参数[]
                        if(typeof target[0] === 'object'){
                            if(!target[0][target[1]]){
                                console.log(target)
                                throw new Error("middleware thereIsNo")
                            }
                            return Middleware.createMiddleware(id,target[0],target[1],target[2]?.split(",").map((e:any)=>parse(e)) || [])
                        }else if(typeof target[0] === 'function'){
                            return Middleware.createMiddleware(id,target[0],"anonymous",target[1]?.split(",").map((e:any)=>parse(e)) || [])
                        }
                    }else{
                        // 判断是不是解析好的中间件
                        if(target.isInterface)return target;
                        if(target[methodName]){
                            return Middleware.createMiddleware(id,target,methodName,[])
                        }
                        throw new Error("middleware is type Err")
                    }
                }
                default : {
                    if(target === undefined){
                      console.log(color("red",id+" 模块不存在"))
                        throw new Error("module thereIsNo")
                    }
                    throw new Error("middleware type is Err")
                }
            }
        }
        // 正常解析中间件
        if(Array.isArray(target)){
            return target.map(e=>pars(id, e, methodName))
        }else{
            return pars(id, target, methodName)
        }
    }
    
    /**
     * 
     * @param filepath 文件路径 File address
     * @param methodName 方法方法名称 
     * @param param 参数
     * @returns 
     */
    public static pars_string_middleware(filepath:string,methodName:string,param:Array<any>):ControllerStructure{
        let midd = loader(filepath,true);
        if(midd instanceof Promise){
            let middleware_module:ControllerStructure = new ControllerStructure("",()=>{return "初始化未完成：middlewared:101"},param);
            process.nextTick(async ()=>{
                midd = await midd;
                let module = Middleware.createMiddleware(filepath,midd,methodName,param)
                middleware_module.module.run = module.module.run;
            })
            return middleware_module;
        }else{
            return Middleware.createMiddleware(filepath,midd,methodName,param)
        }
    }

    /**
     * 创建中间件模块
     * @param filepath   文件路径
     * @param midd       需要执行的核心部分 
     * @param methodName 方法名称
     * @param param       执行参数
     * @returns 
     */
    public static createMiddleware(filepath:string,midd:any,methodName:string,param:Array<string>):ControllerStructure {
        let judge = (midd:any,methodName:string,path:string,param:Array<string>)=>{
            if(typeof midd[methodName] !== "function"){
                console.log(color("红色",methodName+" 必须为方法"))
                console.log(color("蓝色",path))
                ErrorUtils.error("中间件或控制器必须为方法")
            };
            // 存在,开始生成中间件
            return new ControllerStructure(methodName,(...param:any[])=>{return midd[methodName](...param);},param);
        }

        if(Class.isClass(midd)){
            // 这是一个类
            midd = midd[methodName] ? midd : new midd();
            if(midd[methodName]){
                // 检查中间件并且处理
                return judge(midd,methodName,filepath,param);
            }else{
                console.log(color("红色",methodName+" 不存在"))
                console.log(color("蓝色",filepath))
                ErrorUtils.error("中间件不存在")
            }
        }else if(typeof midd === "object"){
            if(midd[methodName]){
                // 检查中间件并且处理
                return judge(midd,methodName,filepath,param);
            }else{
                console.log(color("红色",methodName+" 不存在"))
                console.log(color("蓝色",filepath))
                ErrorUtils.error("中间件不存在")
            }
        }else if(typeof midd === 'function'){
            return new ControllerStructure(methodName,async (...param:any[])=>{return await midd(...param);},param);
        }else{
            // 类型错误
            console.log(color("红色",methodName+" 中间件类型错误 "+typeof midd)+midd)
            console.log(color("蓝色",filepath))
            ErrorUtils.error("中间件类型错误")
        }
        return null;
    }

    // 解析字符串中间件
}